#pragma once
#include <map>
#include <memory>
#include "ConfigInfo.h"
#include "XnccThread.h"
#include "XnccType.h"
namespace xncc {
namespace msg {
    class MsgRingList;
    class FIFOQueue;
}  // namespace msg
namespace foundation {
    class EventLoop;
    class XnccServer;
    class XnccClient;
    class Channel;

    class LoopManager
    {
      public:
        LoopManager() = default;

        int init(const config::PlatformInfo& cfg);
        // 业务线程有绑定用户回调函数的需求，因此需要获取loop，
        std::shared_ptr<EventLoop> getLoop(types::thread_id_t tid);
        std::shared_ptr<EventLoop> getIpcLoop(types::thread_id_t tid);
        XnccServer*                getXnccServer(types::thread_id_t tid);

        void startAll();
        void joinAll();
        void stopAll();
        ~LoopManager();

        LoopManager(const LoopManager&)             = delete;
        LoopManager(const LoopManager&&)            = delete;
        LoopManager& operator=(const LoopManager&)  = delete;
        LoopManager& operator=(const LoopManager&&) = delete;

        int subQueue(types::thread_id_t  tid,
                     types::queue_id_t   queueId,
                     types::queue_size_t queueSize,
                     bool                autoExpand = false);

      private:
        void initBusiThreads(const config::PlatformInfo& cfg);
        void initIpcServers(const config::PlatformInfo& cfg);
        void initIpcClients(const config::PlatformInfo& cfg);
        void initIpcRecvQueues(const config::PlatformInfo& cfg);

        /// 业务线程绑定TCP线程使用的管道的channel
        void bindChannel();

        /// 由于有排序，所以可以让第一个事件循环 由主main函数线程执行
        std::map<types::thread_id_t, std::shared_ptr<EventLoop>> busiLoops_;
        std::map<types::thread_id_t, std::shared_ptr<EventLoop>> ipcLoops_;  /// IPC线程的事件循环
        std::map<types::thread_id_t, std::unique_ptr<PThread>>   threads_;
        std::map<types::thread_id_t, XnccServer*>                servers_;
        std::map<types::thread_id_t, XnccClient*>                clients_;
    };
}  // namespace foundation
}  // namespace xncc